/* Anastasia Shuba
   Carolyn Ngo
   EECS22L
   01/14/12 
	Updates: 
	01/16/12 @ 11am - Nastia: fixed double precision on uneven division.

--------------------------------------------------------------
	ISSUES TO FIX: after acc is promoted to double reading how do we know to make it go back to int reading?
			underflow, overflow - ????
			valgrind leaks due to readline
*/

#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <string.h>

int manageHistory();

int main()
{
	char *cp;
	char sign[1];
	unsigned char DoubleOrInt;
	int numOfArg, num1, num2;
	double acc;
	numOfArg=num1=num2=0;
	acc=0;
	DoubleOrInt=0;
	cp=NULL;

	manageHistory();

	while(1)
	{	
		if(DoubleOrInt==0) printf("%.0f", acc);
		else printf("%4.2f", acc);

		cp=readline(":");
		if(cp !=NULL) 
		{ 
			add_history(cp); 
			write_history("history.txt");
		}

		numOfArg=sscanf(cp, "%d %s %d", &num1, sign, &num2);

		if(numOfArg == EOF) 
		{ 
			free(cp);
			break; 
		}

		/*For ops with only one number*/
		else if(num1 == 0 && numOfArg < 3) 
		{
			numOfArg=sscanf(cp, "%s %d", sign, &num2);
			
			if(strcmp(sign, "0") != 0)
			{

		 		if( (strlen(sign) > 1) || num2==0 ) printf("Invalid input!\n");

				else if(strcmp(sign, "+") == 0)
				{
					acc=acc+num2;
				}

				else if(strcmp(sign, "-") == 0)
				{
					acc=acc-num2;
				}

				else if(strcmp(sign, "*") == 0)
				{
					acc=acc*num2;
				}

				else if(strcmp(sign, "/") == 0)
				{
					if(num2==0) printf("Error: cannot divide by zero.\n");
					else if((int)acc%num2 != 0)
					{
					 	DoubleOrInt=1;
					 	acc=(double)(acc/num2);
					}
					else acc=acc/num2;
				}
				free(cp);
			}

			else /*if only a number is being entered without a sign - like 0*/
			{
				numOfArg=sscanf(cp, "%d", &num2);
				free(cp);
				acc=num2;
			}
		}
		
		/*protection against input like "2 +3" or "2 +*/
		else if(num2==0 && numOfArg == 2)
		{
			printf("Invalid input. Please enter spaces between binary operators and numbers, and be sure to write both numbers if perfroming a binary operation\n");
		}
		
		/* Positive/Negative numbers being entered */
		else if( num2==0 && numOfArg == 1 ) 
		{
			numOfArg=sscanf(cp, "%d", &num2);
			free(cp);
			acc=num2;
		}

		/* For ops with 2 numbers*/
		else if(numOfArg == 3)
		{
			if(strcmp(sign, "+") == 0)
			{
				acc=num1+num2;
			}

			else if(strcmp(sign, "-") == 0)
			{
				acc=num1-num2;
			}

			else if(strcmp(sign, "*") == 0)
			{
				acc=num1*num2;
			}

			else if(strcmp(sign, "/") == 0)
			{
				if(num2==0) printf("Error: cannot divide by zero.\n");
				else if(num1%num2 != 0)
				{
					 DoubleOrInt=1;
					 acc= (double) num1/num2;
				}
				else acc=num1/num2;
			}
		}

		else 
		{
			printf("Invalid input!\n");
		}
		/*for the next loop*/
		num1=num2=numOfArg=0;
		sign[0]=0;
		
	}
	return 0;
}


int manageHistory()
{
	FILE *History;
	int x;
	History = fopen("history.txt", "r");

	if( History == 0 ) 
	{
		printf("Could not open history of commands.\n");
		return 1;
	}
	
	else if(fgetc(History) == EOF) return 0;
	
	else
	{
		x=read_history("history.txt");
		if(x !=0 )
		{
			 printf("Error while reading history file.\n");
			return 2;
		}
		else return 0;
	}
}






























	
